#region license
# This file is part of Grawlix.
# 
# Grawlix is free software: you can redistribute it and/or modify
# it under the terms of the GNU General Public License as
# published by the Free Software Foundation, either version 3 of
# the License, or (at your option) any later version.
# 
# Grawlix is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
# GNU General Public License for more details.
# 
# You should have received a copy of the GNU General Public
# License along with Grawlix.  If not, see
# <http://www.gnu.org/licenses/>.
#endregion

"""Various types of input messages."""

namespace Grawlix.Application.Gui
import Grawlix
import Grawlix.Services
import System

abstract class InputMessage(Message):
"""Base class of input Messages."""
	
	protected def constructor():
	"""Default constructor."""
		pass

	override def ToString():
	"""
	Get a string representation of this message.
	Returns: A string representation of the message.
	"""
		return "[InputMessage]"

abstract class KeyboardInputMessage(InputMessage):
"""Base class for keyboard input."""
	
	protected def constructor():
	"""Default constructor."""
		pass
	
	override def ToString():
	"""
	Get a string representation of this message.
	Returns: A string representation of the message.
	"""
		return "[KeyboardInputMessage]"

abstract class KeyPressInputMessage(KeyboardInputMessage):
"""Generic base for key down and key up messages."""
	
	protected def constructor(code as int, down as bool):
	"""
	Create a new keypress message.
	Param code: The key code pressed.
	Param down: Whether the key is down.
	"""
		_code = code
		_down = down
	
	override def ToString():
	"""
	Get a string representation of this message.
	Returns: A string representation of the message.
	"""
		return "[KeyPressInputMessage: Code=${Code} Down=${Down}]"

	[property(Code)]
	private _code as int
	"""The received key."""
	
	[property(Down)]
	private _down as bool
	"""Whether the key is down."""

class KeyUpInputMessage(KeyPressInputMessage):
"""Event that occurs when a key becomes up."""
	
	def constructor(code as int):
	"""
	Create a new key up message.
	Param code: The key code pressed.
	"""
		super(code, false)

	override def ToString():
	"""
	Get a string representation of this message.
	Returns: A string representation of the message.
	"""
		return "[KeyUpInputMessage: Code=${Code} Down=${Down}]"

class KeyDownInputMessage(KeyPressInputMessage):
"""
Event that occurs when a key becomes down.
Remarks: It's possible to get multiple key up events
"""
	
	def constructor(code as int):
	"""
	Create a new key up message.
	Param code: The key code pressed.
	"""
		super(code, false)

	override def ToString():
	"""
	Get a string representation of this message.
	Returns: A string representation of the message.
	"""
		return "[KeyDownInputMessage: Code=${Code} Down=${Down}]"

class CharacterInputMessage(KeyboardInputMessage):
"""Character input."""
	
	def constructor(character as char):
	"""
	Create a new character message.
	Param character: The input character.
	"""
		_character = character
	
	override def ToString():
	"""
	Get a string representation of this message.
	Returns: A string representation of the message.
	"""
		return "[CharacterInputMessage: Character=${Character}]"

	[property(Character)]
	private _character as char
	"""The received input character."""

abstract class MouseInputMessage(InputMessage):
"""Generic base for mouse events."""
	
	protected def constructor(position as Vector):
	"""
	Create a new mouse input message.
	Param position: The position of the mouse.
	"""
		_position = position
	
	override def ToString():
	"""
	Get a string representation of this message.
	Returns: A string representation of the message.
	"""
		return "[MouseInputMessage: Position=${Position}]"

	[property(Position)]
	private _position as Vector
	"""The position of the mouse."""

abstract class MouseBoundaryInputMessage(MouseInputMessage):
"""Generic base for mouse leave or enter events."""
	
	protected def constructor(position as Vector):
	"""
	Create a new mouse boundary input message.
	Param position: The position of the mouse.
	"""
		super(position)

	override def ToString():
	"""
	Get a string representation of this message.
	Returns: A string representation of the message.
	"""
		return "[MouseBoundaryInputMessage: Position=${Position}]"

class MouseEnterInputMessage(MouseBoundaryInputMessage):
"""Indication that the mouse has just entered a control."""
	
	def constructor(position as Vector):
	"""
	Create a new mouse enter input message.
	Param position: The position of the mouse.
	"""
		super(position)

	override def ToString():
	"""
	Get a string representation of this message.
	Returns: A string representation of the message.
	"""
		return "[MouseEnterInputMessage: Position=${Position}]"

class MouseLeaveInputMessage(MouseBoundaryInputMessage):
"""Indication that the mouse has just left a control."""
	
	def constructor(position as Vector):
	"""
	Create a new mouse leave input message.
	Param position: The position of the mouse.
	"""
		super(position)

	override def ToString():
	"""
	Get a string representation of this message.
	Returns: A string representation of the message.
	"""
		return "[MouseLeaveInputMessage: Position=${Position}]"

class MouseMoveInputMessage(MouseInputMessage):
"""Mouse movement event."""
	
	def constructor(position as Vector, delta as Vector):
	"""
	Create a new mouse input message.
	Param position: The position of the mouse.
	Param delta: The change in mouse position.
	"""
		super(position)
		_delta = delta
	
	override def ToString():
	"""
	Get a string representation of this message.
	Returns: A string representation of the message.
	"""
		return "[MouseMoveInputMessage: Position=${Position} Delta=${Delta}]"

	[property(Delta)]
	private _delta as Vector
	"""
	Change in mouse position.
	Remarks: It could be a bit different from the
		difference between last frame and this one.
	"""

class MouseWheelInputMessage(MouseInputMessage):
"""Mouse wheel movement."""
	
	def constructor(position as Vector, ticks as int):
	"""
	Create a new mouse wheel input message.
	Param position: The position of the mouse.
	Param ticks: The amount and direction changed on the wheel.
	"""
		super(position)
		_ticks = ticks
	
	override def ToString():
	"""
	Get a string representation of this message.
	Returns: A string representation of the message.
	"""
		return "[MouseWheelInputMessage: Position=${Position} Ticks=${Ticks}]"

	[property(Ticks)]
	private _ticks as int
	"""The amount moved."""

abstract class MouseClickInputMessage(MouseInputMessage):
"""Generic base for mouse up or down events."""
	
	protected def constructor(position as Vector, code as int, down as bool):
	"""
	Create a new mouse click input message.
	Param position: The position of the mouse.
	Param code: The button code pressed.
	Param down: Whether the button is down.
	"""
		super(position)
		_code = code
		_down = down
	
	override def ToString():
	"""
	Get a string representation of this message.
	Returns: A string representation of the message.
	"""
		return "[MouseClickInputMessage: " + \
			"Position=${Position} Code=${Code} Down=${Down}]"

	[property(Code)]
	private _code as int
	"""The button pressed."""
	
	[property(Down)]
	private _down as bool
	"""Whether the button is down."""
	
class MouseDownInputMessage(MouseClickInputMessage):
"""Mouse down events."""
	
	def constructor(position as Vector, code as int):
	"""
	Create a new mouse down input message.
	Param position: The position of the mouse.
	Param code: The button code pressed.
	"""
		super(position, code, true)

	override def ToString():
	"""
	Get a string representation of this message.
	Returns: A string representation of the message.
	"""
		return "[MouseDownInputMessage: " + \
			"Position=${Position} Code=${Code} Down=${Down}]"

class MouseUpInputMessage(MouseClickInputMessage):
"""Mouse up events."""
	
	def constructor(position as Vector, code as int):
	"""
	Create a new mouse up input message.
	Param position: The position of the mouse.
	Param code: The button code pressed.
	"""
		super(position, code, false)

	override def ToString():
	"""
	Get a string representation of this message.
	Returns: A string representation of the message.
	"""
		return "[MouseUpInputMessage: " + \
			"Position=${Position} Code=${Code} Down=${Down}]"

	

